package net.dgg.dggcloud.service.jrcrm.common.webscoket;

import net.dgg.dggcloud.service.jrcrm.common.webscoket.redis.dao.WSRedisDAO;
import net.dgg.dggcloud.service.jrcrm.constant.CommonConstant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class SystemWebSocketHandler implements WebSocketHandler {

    private static Logger logger = LoggerFactory.getLogger(SystemWebSocketHandler.class);

    private static final Map<String, WebSocketSession> users = new ConcurrentHashMap<>();

    @Resource
    private WSRedisDAO wsRedisDAO;

    /**
     * 连接后
     *
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        Map<String, Object> params = session.getAttributes();
        String uId = String.valueOf(params.get(CommonConstant.WEBSOCKET_USER_SESSION));
        users.put(session.hashCode() + ":" + uId, session);
        wsRedisDAO.sendHashMapByOnlineUser(session);
        logger.info("ws连接成功：" + session.getAttributes().toString() + " 连接数量：" + users.size());
    }

    /**
     * 处理发送过来的消息
     *
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        logger.info("用户发送消息:" + session.getAttributes().toString());
    }

    /**
     * 客户端 异常断开
     *
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        try {
            Map<String, Object> params = session.getAttributes();
            users.remove(session.hashCode() + ":" + params.get(CommonConstant.WEBSOCKET_USER_SESSION));
            logger.info("ws连接异常断开(已被移除Map)：" + params.toString() + " 连接数量：" + users.size());
            if (session.isOpen()) {
                session.close();
            }

            if (params != null) {
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    if (entry.getKey().equals(CommonConstant.WEBSOCKET_USER_LOGINNAME)) {
                        wsRedisDAO.delHashMapByOnlineUser(session.hashCode() + ":" + entry.getValue());
                        break;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("客户端异常断开异常：", e);
        }
    }

    /**
     * 连接已经断开
     *
     * @param session
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        try {
            Map<String, Object> params = session.getAttributes();
            users.remove(session.hashCode() + ":" + String.valueOf(params.get(CommonConstant.WEBSOCKET_USER_SESSION)));
            logger.info("ws连接正常断开（从Map中移除）：" + params.toString() + " 连接数量：" + users.size());
            if (params != null) {
                for (Map.Entry<String, Object> entry : params.entrySet()) {
                    if (entry.getKey().equals(CommonConstant.WEBSOCKET_USER_LOGINNAME)) {
                        wsRedisDAO.delHashMapByOnlineUser(session.hashCode() + ":" + entry.getValue());
                        break;
                    }
                }
            }
        } catch (Exception e) {
            logger.error("客户端正常断开异常：", e);
        }
    }

    /**
     * 握手成功初始化操作在这里面进行
     *
     * @return
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 给所有在线用户发送消息
     *
     * @param message
     */
    public void sendMessageToUsers(TextMessage message) {
        Collection<WebSocketSession> userList = users.values();
        for (WebSocketSession user : userList) {
            try {
                if (user.isOpen()) {
                    user.sendMessage(message);
                }
            } catch (Exception e) {
                logger.error("给所有用户发送信息失败，session信息：" + user.getAttributes().toString(), e);
            }
        }

    }

    /**
     * 给某个用户发送消息
     *
     * @param receiver 接收人名称
     * @param message
     */
    public boolean sendMessageToUser(Long receiver, TextMessage message) {
        WebSocketSession user;
        for (Map.Entry<String, WebSocketSession> entry : users.entrySet()) {
            String keys[] = entry.getKey().split(":");
            if (keys[1].equals(String.valueOf(receiver))) {
                try {
                    user = entry.getValue();
                    if (user.isOpen()) {
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    logger.error("给用户" + receiver + "发送消息失败！", e);
                }
            }
        }
        return false;
    }

}